package shark.auth.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import shark.auth.filter.JwtAuthenticationFilter;
import shark.auth.handler.*;
import shark.auth.provider.UserAuthenticationProvider;

/**
 * 系统安全核心配置
 * 
 * @author 唐浩宇
 *
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) // 开启方法权限注解
public class SharkSecurityConfig extends WebSecurityConfigurerAdapter {

	/**
	 * 无权限处理类
	 */
	@Autowired
	private UserAccessDeniedHandler userAccessDeniedHandler;

	/**
	 * 用户未登录处理类
	 */
	@Autowired
	private UserNotLoginHandler userNotLoginHandler;

	/**
	 * 用户登录成功处理类
	 */
	@Autowired
	private UserLoginSuccessHandler userLoginSuccessHandler;

	/**
	 * 用户登录失败处理类
	 */
	@Autowired
	private UserLoginFailureHandler userLoginFailureHandler;

	/**
	 * 用户登出成功处理类
	 */
	@Autowired
	private UserLogoutSuccessHandler userLogoutSuccessHandler;

	/**
	 * 用户登录验证
	 */
	@Autowired
	private UserAuthenticationProvider userAuthenticationProvider;

	/**
	 * 加密方式
	 * 
	 * @return
	 */
	@Bean
	public BCryptPasswordEncoder bCryptPasswordEncoder() {
		return new BCryptPasswordEncoder();
	}

	/**
	 * 用户登录验证
	 */
	@Override
	protected void configure(AuthenticationManagerBuilder auth) {
		auth.authenticationProvider(userAuthenticationProvider);
	}

	/**
	 * 安全权限配置
	 */
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.authorizeRequests() // 权限配置
				.antMatchers(JWTConfig.antMatchers.split(",")).permitAll()// 获取白名单（不进行权限验证）
				.antMatchers(HttpMethod.OPTIONS).permitAll()
				.anyRequest().authenticated() // 其他的需要登陆后才能访问
				.and().httpBasic().authenticationEntryPoint(userNotLoginHandler) // 配置未登录处理类
				.and().formLogin().loginProcessingUrl("/login")// 配置登录URL
				.successHandler(userLoginSuccessHandler) // 配置登录成功处理类
				.failureHandler(userLoginFailureHandler) // 配置登录失败处理类
				.and().logout().logoutUrl("/logout")// 配置登出地址
				.logoutSuccessHandler(userLogoutSuccessHandler) // 配置用户登出处理类
				.and().exceptionHandling().accessDeniedHandler(userAccessDeniedHandler)// 配置没有权限处理类
				.and().cors()// 开启跨域
				.and().csrf().disable(); // 禁用跨站请求伪造防护
		http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); // 禁用session（使用Token认证）
		http.headers().cacheControl(); // 禁用缓存
		http.addFilter(new JwtAuthenticationFilter(authenticationManager())); //// 添加JWT过滤器
	}

	/**
	 * 允许跨域调用的过滤器
	 */
	@Bean
	public CorsFilter corsFilter() {
		CorsConfiguration config = new CorsConfiguration();
		//允许所有域名进行跨域调用
//		config.addAllowedOrigin("*");
		config.addAllowedOriginPattern("*");
		//允许跨越发送cookie
		config.setAllowCredentials(true);
		//放行全部原始头信息
		config.addAllowedHeader("*");
		//允许所有请求方法跨域调用
		config.addAllowedMethod("*");
		UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
		source.registerCorsConfiguration("/**", config);
		return new CorsFilter(source);

	}

}